# Build help files for DC++
# Dependencies:
# - Perl, in order to use po4a <http://po4a.alioth.debian.org/>
# - Microsoft HTML Help Workshop <http://msdn2.microsoft.com/en-us/library/ms670169.aspx>

Import('dev')
env = dev.env.Clone()

import os
from util import array_remove

# static_HTMLs holds static (not dynamically generated) HTML sources
static_HTMLs = Glob('*.html', strings = 1)
static_HTMLs.sort()
array_remove(static_HTMLs, 'changelog.html')
array_remove(static_HTMLs, 'compile.html')
array_remove(static_HTMLs, 'fdl.html')

# cshelp.h is included in resource.h, which in turn is included in the DC++
# source; hence, we generate it even when help files are not being compiled.
from gen_cshelp import gen_cshelp
env.Command('cshelp.h', static_HTMLs, Action(lambda target, source, env: gen_cshelp(target, source), 'Generating $TARGET'))
env.Depends('resource.h', 'cshelp.h')

if not env['help']:
	Return()

if env['mode'] != 'release' and not env['i18n']:
	Return()

if env.WhereIs('perl') is None:
	print 'Perl is required to run po4a scripts, skipping help build'
	Return()

env['asciidoc'] = dev.get_asciidoc()
if env['asciidoc'] is None:
	print 'asciidoc is required to process Compile.txt, skipping help build'
	Return()

# fix hhc.exe reverse return value - UGLY - taken from the NSIS build system
old_spawn = env['SPAWN']
def new_spawn(*args, **kw):
	result = old_spawn(*args, **kw)
	if 'hhc' in args[3]:
		return not result
	else:
		return result
env['SPAWN'] = new_spawn

# generate changelog.html
from gen_changelog import gen_changelog
env.Command('changelog.html', ['#/changelog.txt', 'template.html'], Action(gen_changelog, 'Generating $TARGET'))

# generate compile.html
from gen_compile import gen_compile
env.Command('compile.html', ['#/Compile.txt', 'template.html'], Action(gen_compile, 'Generating $TARGET'))

if env['webhelp']:
	# copy static webhelp files
	web_files = Glob('webhelp/*')
	web_files.append('external.png')
	web_files.append('office11.css')
	web_files.append('style.css')
	for file in Glob('#/res/*.bmp'):
		web_files.append(file)
	for file in Glob('#/res/*.ico'):
		web_files.append(file)
	for file in Glob('#/res/*.png'):
		web_files.append(file)

	for file in web_files:
		name = os.path.basename(str(file))
		if name == 'htaccess': # otherwise, SCons' Glob ignores it
			name = '.htaccess'
		env.Command('#/build/webhelp/' + name, file, Copy('$TARGET', '$SOURCE'))

# define which source files need to be copied to the build directory
CHM_sources = Glob('*.html')
CHM_sources.append('DCPlusPlus.hhp')
CHM_sources.append('external.png')
CHM_sources.append('index.hhk')
CHM_sources.append('office11.css')
CHM_sources.append('resource.h')
CHM_sources.append('style.css')
CHM_sources.append(Glob('#/res/*.bmp'))
CHM_sources.append(Glob('#/res/*.ico'))
CHM_sources.append(Glob('#/res/*.png'))
CHM_sources.sort()

# additional dependencies (that have to be built before the help file)
CHM_dependencies = ['addendum.txt', 'cshelp.h']

from build_util import gen_po_name
import filecmp
from gen_toc import gen_toc
from set_hhp_locale import set_hhp_locale
from util import nixify, scoped_cmd, get_lcid

po4a_path = Dir('#/po4a').abspath + '/'
env['po4a_cmd'] = lambda prog, options: 'perl -I"' + po4a_path + 'lib" "' + po4a_path + prog + '" -f xhtml -o "translated=p<placeholder> p<placeholder><a>" -o "untranslated=<untranslated> <untranslated><a> <untranslated><li>" -o foldattributes -o "includessi=' + nixify(Dir('#/help').abspath) + '/" -M utf-8 -L utf-8 ' + options

# define our CHM builder
def gen_CHM(target, source, env):
	# create the temporary build directory
	build_dir = 'build/help'
	build_path = build_dir + '/'
	env.Execute([Delete(build_dir), Mkdir(build_dir)])
	dir_cleaner = scoped_cmd(lambda: env.Execute(Delete(build_dir)))

	# find the translation file
	po_node = None
	for node in source:
		if node.path[-3:] == '.po' or node.path[-4:] == '.pot':
			po_node = node
			source.remove(node)
	if po_node is None:
		print 'No translation file found when trying to build ' + str(target[0]) + '.'
		return 1

	template = po_node.path[-4:] == '.pot'
	if template:
		lang = 'en-US'
		lcid = 0x409
	else:
		lang = os.path.basename(po_node.path).replace('.po', '')
		lcid = get_lcid(lang)

	if env['webhelp']:
		# create the dir for localized web help files
		web_dir = 'build/webhelp/' + lang.replace('_', '-')
		env.Execute([Delete(web_dir), Mkdir(web_dir)])

	# translate translatable source files, copy the others
	cmd = env['po4a_cmd']('po4a-translate', '-p "' + nixify(str(po_node)) + '" -k 0')
	if not template:
		cmd += ' -A utf-8 -a help/addendum.txt'
	for node in source:
		filename = os.path.basename(node.path)
		if filename[-5:] == '.html' and filename != 'changelog.html' and filename != 'compile.html' and filename != 'fdl.html':
			ret = env.Execute(Action(cmd + ' -m "' + nixify(str(node)) + '" -l "' + nixify(build_path) + filename + '"', 'Translating ' + str(node) + ' using ' + str(po_node)))
		else:
			ret = env.Execute(Copy(build_dir, node))
		if ret:
			return ret

	# generate context-sensitive help files (cshelp.h and cshelp.rtf)
	print 'Generating ' + build_path + 'cshelp.h and ' + str(target[1])
	gen_cshelp([build_path + 'cshelp.h', str(target[1])], Glob(build_path + '*.html'))

	# make sure the generated cshelp.h is the same as the vanilla one
	if not filecmp.cmp(build_path + 'cshelp.h', 'help/cshelp.h'):
		print 'The generated cshelp.h file is not the same as the vanilla one; ' + str(target[0]) + ' won\'t be compiled.'
		env.Execute(Delete(target[1])) # remove the wrong cshelp.rtf
		return 1

	if lcid != 0x409:
		# edit the project file so it is set to the correct locale
		set_hhp_locale(build_path + 'DCPlusPlus.hhp', lcid)

	# generate tables of contents
	toc_targets = [build_path + 'toc.hhc']
	print 'Generating ' + toc_targets[0] + ' (HTML Help TOC)'
	if env['webhelp']:
		toc_targets.append(web_dir + '/toc.inc')
		print 'Generating ' + toc_targets[1] + ' (web help TOC)'
	gen_toc(toc_targets, build_path + 'index.html', lcid)

	# compile the CHM file in the build directory
	CHM_path = build_path + 'DCPlusPlus.chm'
	log_path = build_path + 'hhc.log'
	HHP_path = build_path + 'DCPlusPlus.hhp'
	ret = env.Execute(Action('hhc "' + HHP_path + '" > "' + log_path + '"', 'Compiling the ' + CHM_path + ' temporary help file; log output: ' + log_path))
	if ret:
		return ret

	# copy the compiled file to its final target
	env.Execute(Copy(target[0], CHM_path))

	if env['webhelp']:
		# copy newly translated files to the webhelp dir
		print 'Copying web help files to ' + web_dir
		for file in Glob(build_path + '*.html'):
			env.Execute(Copy(web_dir, file))

		# generate name.txt
		name_file = File(web_dir + '/name.txt')
		print 'Generating ' + str(name_file)
		if template:
			open(str(name_file), 'wb').write('English (United States)')
		else:
			env['NAME_FILE'] = name_file
			gen_po_name(po_node, env)

	return ret
env.Append(BUILDERS = {'CHMBuild' : Builder(action = Action(gen_CHM, 'Compiling the $TARGET help file'))})

hasHHC = env.WhereIs('hhc') is not None

# create the translation template
def gen_pot(target, source, env):
	cmd = env['po4a_cmd']('po4a-gettextize', '-o "package-name=dcpp-help" -o "copyright-holder=Jacek Sieka" -o "msgid-bugs-address=dcplusplus-devel@lists.sourceforge.net" -p "' + nixify(str(target[0])) + '"')
	for node in source:
		cmd += ' -m "' + nixify(str(node)) + '"'
	return env.Execute(cmd)
potfile = File('po/dcpp-help.pot')
env.Command(potfile, static_HTMLs, Action(gen_pot, 'Extracting help texts to $TARGET'))

# update .po's in help/po and compile translated help files
po_list = Glob('po/*.po')
for po_node in po_list:
	env.Precious(env.PoBuild(po_node, potfile))
	if hasHHC:
		target_path = dev.get_build_path('bin') + '/locale/' + os.path.basename(po_node.path).replace('.po', '') + '/help/'
		targets = [target_path + 'DCPlusPlus.chm', target_path + 'cshelp.rtf']
		env.Depends(targets, CHM_dependencies)
		env.CHMBuild(targets, [CHM_sources, po_node])

if not hasHHC:
	print 'hhc.exe not found, skipping chm build'
	Return()

# compile the main (untranslated) help file
target_path = dev.get_build_path('bin') + '/'
targets = [target_path + 'DCPlusPlus.chm', target_path + 'cshelp.rtf']
env.Depends(targets, CHM_dependencies)
ret = env.CHMBuild(targets, [CHM_sources, potfile])

Return('ret')
